var _DnD = {
	clip: null,
	hl:null,
	mode:0,//0: horizontal, 1: vertical
	idx:0,
	clearHL: function(){
		with(this){
			if (hl){
				hl.parentNode.removeChild(hl);
				hl=null;
			}			
		}
	},
	drop:null,//for use in touch mode
	
	emptyDiv:document.createElement('div'),
	makeDragDrop:function(dragElem, dropZone, dropEvent, dragOver, dragStart){
		var clip = null;
		var startPos;
		if (_browser.is_mobile){
			var dropZonePos;
			var dropZoneBottom;
			var touchmove;
			var inside = false;
			var dropPos;
			var touchend;
			dragElem.addEventListener('touchstart', function(e){
				clip = dragElem;
				//_log.innerHTML = 'ts'+(clip==null);
				dropZonePos = _absPos(dropZone);
				dropZoneBottom = {
					x: dropZonePos.x + dropZone.clientWidth,
					y: dropZonePos.y + dropZone.clientHeight
				};
				startPos = {x:e.touches[0].clientX, y:e.touches[0].clientY};
				if (dragStart)
					dragStart(startPos.x, startPos.y);

				touchmove = function(e){
					if (!clip) return;
					//_log.innerHTML = 'tm';
					if (e.touches.length!=1) return;
					e.preventDefault();
					dropPos = {x:e.touches[0].clientX, y:e.touches[0].clientY};
					if (dropZonePos.x <= dropPos.x &&
						dropPos.x <= dropZoneBottom.x &&
						dropZonePos.y <= dropPos.y &&
						dropPos.y <= dropZoneBottom.y){
						inside = true;
						if (dragOver)
							dragOver(dropPos.x, dropPos.y);
					}else {
						inside = false;
						//should be panning here!
						if (dragOver)
							dragOver(startPos.x, startPos.y);
					}
				};
				_root.addEventListener('touchmove', touchmove, false);
				touchend = function(e){
					//_log.innerHTML = 'te'+inside+(clip==null);
					//var str = (clip==null);
					_root.removeEventListener('touchmove', touchmove,false);
					if (clip){
						if (inside){
							dropEvent(dropPos.x, dropPos.y, clip);
							inside = false;
						}
						else if (dragOver){
							dragOver(startPos.x, startPos.y);
						}
					}
					clip = null;
					//_log.innerHTML = str+'cn';
					_root.removeEventListener('touchend', touchend,false);
				};
				_root.addEventListener('touchend', touchend, false);
			},false);
		}else{
			dragElem.draggable = true;
			var dropable = false;
			dragElem.addEventListener('dragstart', function(e){
				if (dragOver){
					if (_browser.is_chrome)
						e.dataTransfer.setDragImage(_DnD.emptyDiv, e.offsetX, e.offsetY);
					startPos = {x:e.clientX, y:e.clientY};
					if (dragStart)
						dragStart(startPos.x, startPos.y);
				}
				else
					e.dataTransfer.setDragImage(dragElem, e.offsetX, e.offsetY);
				//var pos = _absPos(dragElem);
				e.dataTransfer.effectAllowed = "move";
				e.dataTransfer.setData("text/html", dragElem.innerHTML);
				clip = dragElem;
			},false);
			dragElem.addEventListener('dragend', function(e){
				if (clip!=null) //drop outside!
					if (dragOver)
						dragOver(startPos.x, startPos.y);
				clip = null;
			},false);
			dropZone.addEventListener('dragover', function(e){
				if (!clip) return;
				dropable = true;
				if (dragOver)
					dragOver(e.clientX, e.clientY);
				e.preventDefault();
				e.stopPropagation();
				e.dataTransfer.dropEffect = "move";
				return false;
			},false);
			dropZone.addEventListener('dragleave', function(e){
				if (!clip) return;
				dropable = false;
			},false);
			
			dropZone.addEventListener('drop', function(e){
				if (clip && dropable){
					e.stopPropagation();
					dropEvent(e.clientX, e.clientY, clip);
					clip = null;
					return false;
				}
			},false);
		}
	}
}

var UI = {
	start_evt:_browser.is_mobile?'touchstart':'mousedown',
	move_evt:_browser.is_mobile?'touchmove':'mousemove',
	end_evt:_browser.is_mobile?'touchend':'mouseup',
	wdelta:_browser.is_firefox?
		function(e){return e.detail/3;}:
		function(e){return e.wheelDelta/120;},
	makePannable: function(elem, config){
		//default param
		if (!config) config = {};
		if (!('inertia' in config)) config.inertia = false;
		if (!('pinchable' in config)) config.pinchable = false;
		
		if (_browser.is_mobile && _browser.is_safari){
			elem.style.overflow = 'scroll';
			elem.style['-webkit-overflow-scrolling'] = 'touch';
			return;//nothing to do, iOS 5 does it!
		}
		else
		{
			elem.style.overflow = 'hidden';
		}
		var ex,ey,dx,dy;
		var mm = function(e){//mouse move
			if (_browser.is_mobile){
				dx = e.targetTouches[0].clientX;
				dy = e.targetTouches[0].clientY;
			}else{
				dx = e.clientX;
				dy = e.clientY;
			}
			dx -= ex;
			dy -= ey;
			elem.scrollLeft -= dx;
			elem.scrollTop -= dy;
		}
		var mu = function(e){//mouse up
			elem.removeEventListener(UI.move_evt,mm,false);
			_root.removeEventListener(UI.end_evt,mu,false);
		}
		elem.addEventListener(UI.start_evt,function(e){
			elem.removeEventListener(UI.move_evt,mm,false);
			_root.removeEventListener(UI.end_evt,mu,false);
			if (_browser.is_mobile){
				ex = e.targetTouches[0].clientX;
				ey = e.targetTouches[0].clientY;
			}else{
				ex = e.clientX;
				ey = e.clientY;
			}
			elem.addEventListener(UI.move_evt,mm,false);
			_root.addEventListener(UI.end_evt, mu,false);
			//e.preventDefault();
			//return false;
		},false);
		if (_browser.is_desktop && !config.pinchable){
			elem.addEventListener(_browser.is_firefox?'DOMMouseScroll':'mousewheel',
				function(e){
					elem.scrollTop -= UI.wdelta(e)*20;
				}
				,false);
		}
	},
	makeDragDrop:function(dragElem, dropZone, dropEvent, dragOver, dragStart){
		var clip = null;
		var startPos;

		var dropZonePos;
		var dropZoneBottom;
		var touchmove;
		var inside = false;
		var dropPos;
		var touchend;
		dragElem.addEventListener(UI.start_evt, function(e){
			clip = dragElem;
			dropZonePos = _absPos(dropZone);
			dropZoneBottom = {
				x: dropZonePos.x + dropZone.clientWidth,
				y: dropZonePos.y + dropZone.clientHeight
			};
			startPos = _browser.is_mobile?
				{x:e.touches[0].clientX, y:e.touches[0].clientY}:
				{x:e.clientX, y:e.clientY};
			if (dragStart)
				dragStart(startPos.x, startPos.y);

			touchmove = function(e){
				if (!clip) return;
				//if (e.touches.length!=1) return;
				e.preventDefault();
				dropPos = _browser.is_mobile?
					{x:e.touches[0].clientX, y:e.touches[0].clientY}:
					{x:e.clientX, y:e.clientY};
				if (dropZonePos.x <= dropPos.x &&
					dropPos.x <= dropZoneBottom.x &&
					dropZonePos.y <= dropPos.y &&
					dropPos.y <= dropZoneBottom.y){
					inside = true;
					if (dragOver)
						dragOver(dropPos.x, dropPos.y);
				}else {
					inside = false;
					if (dragOver)
						dragOver(startPos.x, startPos.y);
				}
			};
			_root.addEventListener(UI.move_evt, touchmove, false);
			touchend = function(e){
				_root.removeEventListener(UI.move_evt, touchmove,false);
				if (clip){
					if (inside){
						dropEvent(dropPos.x, dropPos.y, clip);
						inside = false;
					}
					else if (dragOver){
						dragOver(startPos.x, startPos.y);
					}
				}
				clip = null;
				_root.removeEventListener(UI.end_evt, touchend,false);
			};
			_root.addEventListener(UI.end_evt, touchend, false);
			e.preventDefault();
			e.stopPropagation();
			return false;

		},false);
	}
}